home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / games / ted5.zip / IGRABSRC.ZIP / GRABVGA.C < prev    next >
C/C++ Source or Header  |  1993-02-04  |  10KB  |  495 lines

  1. ////////////////////////////////////////////////////////////
  2. //
  3. // STANDARD VGA GRABBING
  4. //
  5. ////////////////////////////////////////////////////////////
  6. #include "igrab.h"
  7. #pragma hdrstop
  8.  
  9. ////////////////////////////////////////////////////////////
  10. //
  11. // VGAblit : blits a VGA shape from memory to the VGA screen
  12. //
  13. ////////////////////////////////////////////////////////////
  14. void VGAblit(int x,int y,int width,int height,char huge *buffer)
  15. {
  16.  unsigned ESreg,DIreg,SIreg,DSreg,where,owidth,addx;
  17.  
  18.  if (noshow || SkipToStart)
  19.    return;
  20.  // Preclipping
  21.  if (x<0 || y<0)
  22.    return;
  23.  
  24.  if (x>319 || y>199)
  25.    globalx=globaly=globalmaxh=x=y=0;
  26.  
  27.  addx=0;
  28.  if (x+width>319)
  29.    {
  30.     owidth=width;
  31.     width=320-x;
  32.     addx=owidth-width;
  33.    }
  34.  if (y+height>199)
  35.    {
  36.     height=200-y;
  37.    }
  38.  
  39.  DSreg=FP_SEG(buffer);
  40.  SIreg=FP_OFF(buffer);
  41.  where=y*320+x;
  42.  
  43.  asm    push    si
  44.  asm    push    di
  45.  asm    push    ds
  46.  asm    pushf
  47.  
  48.  asm    cld
  49.  asm    mov    ax,0x0a000
  50.  asm    mov    es,ax
  51.  asm    mov    si,[SIreg]
  52.  asm    mov    ax,[DSreg]
  53.  asm    mov    ds,ax
  54.  
  55.  asm    mov    bx,[y]
  56.  asm    mov    di,[where]
  57.  asm    mov    dx,[height]
  58.  LOOP1:
  59.  asm    mov    cx,[width]
  60.  asm    rep movsb
  61.  asm    mov    cx,[addx]    // any to finish up horizontally?
  62.  asm    jcxz    LOOP1a
  63.  asm    rep lodsb
  64.  
  65.  LOOP1a:
  66.  asm    sub    di,[width]
  67.  asm    add    di,320
  68.  
  69.  LOOP1a0:
  70.  asm    dec    dx
  71.  asm    jnz    LOOP1
  72.  
  73.  asm    popf
  74.  asm    pop    ds
  75.  asm    pop    di
  76.  asm    pop    si
  77. }
  78.  
  79.  
  80. ////////////////////////////////////////////////////////////
  81. //
  82. // DoVGAblit : handles output of VGA grabs to the screen
  83. //
  84. ////////////////////////////////////////////////////////////
  85. void DoVGAblit(int x,int y,int width,int height)
  86. {
  87.  if (noshow || SkipToStart)
  88.    return;
  89.  
  90.  if (nostacking)
  91.    {
  92.     globalx=x;
  93.     globaly=y;
  94.    }
  95.  
  96.  VGAblit(globalx,globaly,width,height,databuffer+offset);
  97.  if (!nostacking)
  98.    {
  99.     globalx+=width;
  100.     if (globalmaxh<height)
  101.       globalmaxh=height;
  102.     if (globalx>320-width)
  103.       {
  104.        globaly+=globalmaxh;
  105.        globalx=globalmaxh=0;
  106.       }
  107.    }
  108. }
  109.  
  110.  
  111. ////////////////////////////////////////////////////////////
  112. //
  113. // VGAgrab : grabs any VGA shape from the screen buffer in main memory
  114. //           with INLINE asm for *FAST* grab!
  115. //         Of course, by John Romero!
  116. //
  117. // NOTE: I expect X & WIDTH to be in BYTE values, not pixels!
  118. //
  119. ////////////////////////////////////////////////////////////
  120. void VGAgrab(int x,int y,int width,int height,unsigned offset)
  121. {
  122.  unsigned ESreg,DIreg,SIreg,DSreg,scrnwid,loc;
  123.  
  124.  scrnwid=CurrentLBM.width;
  125.  loc=y*scrnwid+x;
  126.  
  127.  // FROM
  128.  SIreg=FP_OFF(lbmscreen)+(loc&15);
  129.  DSreg=FP_SEG(lbmscreen)+(loc/16);
  130.  
  131.  // TO
  132.  ESreg=FP_SEG(databuffer+offset);
  133.  DIreg=FP_OFF(databuffer+offset);
  134.  
  135.  asm        push    si
  136.  asm        push    di
  137.  asm        push    ds
  138.  
  139.  asm        mov    bx,height
  140.  asm        mov    dx,width
  141.  
  142.  asm        mov    es,ESreg
  143.  asm        mov    di,DIreg
  144.  asm        mov    si,SIreg
  145.  asm        mov    ax,DSreg
  146.  asm        mov    ds,ax
  147.  asm        cld
  148.  
  149.  LOOP1:
  150.  
  151.  asm        mov    cx,dx
  152.  asm        rep movsb
  153.  
  154.  asm        sub    si,dx
  155.  asm        add    si,scrnwid
  156.  asm        dec    bx
  157.  asm        jnz    LOOP1
  158.  
  159.  asm        pop    ds
  160.  asm        pop    di
  161.  asm        pop    si
  162.  
  163.  offset+=width*height;
  164. }
  165.  
  166. ////////////////////////////////////////////////////////////
  167. ////////////////////////////////////////////////////////////
  168. //
  169. // MASKED STUFF
  170. //
  171. ////////////////////////////////////////////////////////////
  172. ////////////////////////////////////////////////////////////
  173.  
  174.  
  175. ////////////////////////////////////////////////////////////
  176. //
  177. // VGAMblit : blits a VGA masked shape from memory to the VGA screen
  178. //
  179. ////////////////////////////////////////////////////////////
  180. void VGAMblit(int x,int y,int width,int height,char huge *buffer)
  181. {
  182.  unsigned MASKoff,DATAoff,ESreg,DIreg,SIreg,DSreg,where,oheight,owidth,addx;
  183.  
  184.  if (noshow || SkipToStart)
  185.    return;
  186.  // Preclipping
  187.  if (x<0 || y<0)
  188.    return;
  189.  
  190.  addx=0;
  191.  owidth=width;
  192.  oheight=height;
  193.  
  194.  if (x+width>319)
  195.    {
  196.     width=320-x;
  197.     addx=owidth-width;
  198.    }
  199.  if (y+height>199)
  200.    {
  201.     height=200-y;
  202.    }
  203.  
  204.  DSreg=FP_SEG(buffer);
  205.  MASKoff=FP_OFF(buffer);
  206.  DATAoff=FP_OFF((char far *)buffer+owidth*oheight);
  207.  where=y*320+x;
  208.  
  209.  asm    push    si
  210.  asm    push    di
  211.  asm    push    ds
  212.  asm    pushf
  213.  
  214.  asm    mov    dx,[DATAoff]
  215.  asm    mov    ds,[DSreg]
  216.  
  217.  asm    mov    si,[MASKoff]
  218.  asm    mov    di,[where]
  219.  asm    mov    ax,0xa000
  220.  asm    mov    es,ax
  221.  
  222.  asm    mov    bl,[BYTE PTR y]
  223.  asm    mov    bh,[BYTE PTR height]
  224.  LOOP1:
  225.  asm    mov    cx,[width]
  226.  LOOP1c:
  227.  asm    mov    al,[es:di]
  228.  asm    and    al,[si]        // get mask byte (SI=mask data)
  229.  asm    inc    si
  230.  asm    xchg    si,dx        // SI now = VGA data
  231.  asm    or    al,[si]
  232.  asm    inc    si
  233.  asm    xchg    si,dx        // SI now = MASK data
  234.  asm    stosb
  235.  asm    loop LOOP1c
  236.  asm    mov    cx,[addx]    // any to finish up horizontally?
  237.  asm    jcxz    LOOP1a
  238.  asm    add    si,cx
  239.  asm    add    dx,cx
  240.  
  241.  LOOP1a:
  242.  asm    sub    di,[width]    // calculate next VGA line
  243.  asm    add    di,320
  244.  
  245.  LOOP1a0:
  246.  asm    dec    bh
  247.  asm    jnz    LOOP1
  248.  
  249.  asm    popf
  250.  asm    pop    ds
  251.  asm    pop    di
  252.  asm    pop    si
  253. }
  254.  
  255.  
  256. ////////////////////////////////////////////////////////////
  257. //
  258. // DoVGAMblit : handles output of masked EGA grabs to the screen
  259. //
  260. ////////////////////////////////////////////////////////////
  261. void DoVGAMblit(int x,int y,int width,int height,int yadd,int hadd)
  262. {
  263.  int i,j;
  264.  
  265.  if (noshow || SkipToStart)
  266.    return;
  267.  
  268.  if (nostacking)
  269.    {
  270.     globalx=x;
  271.     globaly=y;
  272.     yadd=hadd=0;
  273.    }
  274.  else
  275.  if (yadd || hadd)
  276.    {
  277.     char huge *VGAscrn=MK_FP(0xa000,0);
  278.  
  279.     for (j=globaly;j<globaly+yadd;j++)
  280.       for (i=globalx;i<globalx+width;i++)
  281.     *(VGAscrn+j*320+i)^=0x55;
  282.  
  283.     for (j=globaly+yadd+height;j<height+globaly+yadd+hadd;j++)
  284.       for (i=globalx;i<globalx+width;i++)
  285.     *(VGAscrn+j*320+i)^=0x55;
  286.    }
  287.  
  288.  VGAMblit(globalx,globaly+yadd,width,height,databuffer+offset);
  289.  if (!nostacking)
  290.    {
  291.     globalx+=width;
  292.     if (globalmaxh<height)
  293.       globalmaxh=height;
  294.     if (globalx>320-width)
  295.       {
  296.        globaly+=globalmaxh;
  297.        globalx=globalmaxh=0;
  298.       }
  299.    }
  300. }
  301.  
  302.  
  303. ////////////////////////////////////////////////////////////
  304. //
  305. // VGAMgrab: grabs any masked VGA shape from the screen buffer in main memory
  306. //           with INLINE asm for *FAST* grab!
  307. //         Of course, by John Romero!
  308. //
  309. ////////////////////////////////////////////////////////////
  310. void VGAMgrab(int x,int y,int width,int height,unsigned offset,int optimize)
  311. {
  312.  unsigned j,maskoff,ESreg,DIreg,SIreg,DSreg,scrnwid,tmpset=0;
  313.  
  314.  scrnwid=CurrentLBM.width;
  315.  
  316.  //
  317.  // Does caller want vertical-seek optimization?
  318.  //
  319.  if (optimize)
  320.    {
  321.     Optimum.height=Optimum.y=0;
  322.  
  323.     for (i=y;i<y+height;i++)
  324.       {
  325.        for (j=x;j<x+width;j++)
  326.      if (*(maskscreen+i*scrnwid+j)!=0xff)
  327.        { Optimum.y=i; break; }
  328.        if (Optimum.y)
  329.      break;
  330.       }
  331.  
  332.     for (i=y+height-1;i>=0;i--)
  333.       {
  334.        for (j=x;j<x+width;j++)
  335.      if (*(maskscreen+i*scrnwid+j)!=0xff)
  336.        { Optimum.height=i-y; break; }
  337.        if (Optimum.height)
  338.      break;
  339.       }
  340.  
  341.     if (Optimum.height && Optimum.height!=height)
  342.       height=Optimum.height-(Optimum.y-y)+1;
  343.  
  344.     if (Optimum.y && Optimum.y!=y)
  345.       y=Optimum.y;
  346.    }
  347.  
  348.  
  349.  // FROM
  350.  SIreg=FP_OFF(maskscreen)+((scrnwid*y+x)&15);
  351.  DSreg=FP_SEG(maskscreen)+((scrnwid*y+x)/16);
  352.  
  353.  // TO
  354.  ESreg=FP_SEG(databuffer+offset);
  355.  DIreg=FP_OFF(databuffer+offset);
  356.  
  357.  asm        push    si
  358.  asm        push    di
  359.  asm        push    ds
  360.  
  361.  asm        mov    bx,[height]
  362.  asm        mov    dx,[width]
  363.  
  364.  asm        mov    es,[ESreg]
  365.  asm        mov    di,[DIreg]
  366.  asm        mov    si,[SIreg]
  367.  asm        mov    ax,[DSreg]
  368.  asm        mov    ds,ax
  369.  asm        cld
  370.  
  371.  LOOP0:
  372.  
  373.  asm        mov    cx,dx
  374.  LOOP00:
  375.  asm        lodsb
  376.  asm        or    al,al
  377.  asm        jz    LOOP01
  378.  asm        mov    al,0xff        // Make MASK color ALWAYS 0xFF!
  379.  asm        mov    [tmpset],1
  380.  
  381.  LOOP01:
  382.  asm        stosb
  383.  asm        loop    LOOP00
  384.  
  385.  asm        sub    si,dx
  386.  asm        add    si,[scrnwid]
  387.  asm        dec    bx
  388.  asm        jnz    LOOP0
  389.  
  390.  asm        pop    ds
  391.  asm        pop    di
  392.  asm        pop    si
  393.  
  394.  maskoff=DIreg;
  395.  
  396.  // FROM
  397.  SIreg=FP_OFF(lbmscreen)+((scrnwid*y+x)&15);
  398.  DSreg=FP_SEG(lbmscreen)+((scrnwid*y+x)/16);
  399.  
  400.  // TO
  401.  DIreg+=width*height;
  402.  
  403.  asm        push    si
  404.  asm        push    di
  405.  asm        push    ds
  406.  
  407.  asm        mov    dx,[width]
  408.  
  409.  asm        mov    es,[ESreg]
  410.  asm        mov    di,[DIreg]    // DI=VGA data offset
  411.  asm        mov    si,[SIreg]    // SI=VGA screen offset
  412.  asm        mov    ds,[DSreg]
  413.  asm        mov    bx,[maskoff]    // BX=mask offset
  414.  asm        mov    ah,[BYTE PTR height]
  415.  
  416.  LOOP1:
  417.  asm        mov    cx,dx
  418.  
  419.  LOOP2:
  420.  asm        lodsb            // get VGA data
  421.  asm        mov    ch,[es:bx]    // get mask byte
  422.  asm        xor    ch,0xff        // and invert it!
  423.  asm        and    al,ch        // AND with mask
  424.  asm        xor    ch,ch        // make sure LOOP keeps going!
  425.  asm        stosb            // store
  426.  asm        inc    bx        // next mask byte
  427.  asm        loop LOOP2        // do all VGA bytes
  428.  
  429.  asm        sub    si,dx
  430.  asm        add    si,[scrnwid]
  431.  asm        dec    ah
  432.  asm        jnz    LOOP1
  433.  
  434.  asm        pop    ds
  435.  asm        pop    di
  436.  asm        pop    si
  437.  
  438.  //
  439.  // SEE IF WE NEED TO ELIMINATE THE MASK & SET THE
  440.  // BIT IN THE PACKED-BIT ARRAY. MASK-ELIMINATION IS
  441.  // DONE BY MOVING THE TILE DATA BACK OVER THE MASK.
  442.  //
  443.  setbit=tmpset^1;
  444.  
  445.  if (bit && setbit)
  446.    {
  447.     char masks[8]={0x80,0x40,0x20,0x10,8,4,2,1};
  448.     unsigned psize=width*height,domove=0;
  449.  
  450.     switch(type)
  451.     {
  452.      case TILE8MTYPE:
  453.      case ALT8MTYPE:
  454.        if (!cmpt8)
  455.      break;
  456.  
  457.        T8bit[T8whichbit/8]|=masks[T8whichbit%8];
  458.        domove=1;
  459.        break;
  460.      case TILE16MTYPE:
  461.      case ALT16MTYPE:
  462.        T16bit[T16whichbit/8]|=masks[T16whichbit%8];
  463.        domove=1;
  464.        break;
  465.      case TILE32MTYPE:
  466.      case ALT32MTYPE:
  467.        T32bit[T32whichbit/8]|=masks[T32whichbit%8];
  468.        domove=1;
  469.     }
  470.  
  471.     if (domove)
  472.       {
  473.        asm    push    si
  474.        asm    push    di
  475.        asm    push    ds
  476.  
  477.        asm    mov    si,[DIreg]
  478.        asm    mov    ax,[ESreg]
  479.        asm    mov    ds,ax
  480.        asm    mov    es,ax        // ES:DI - mask data
  481.        asm    mov    di,si
  482.        asm    add    si,[psize]    // DS:SI = tile data
  483.  
  484.        asm    mov    cx,[psize]    // move all tile data
  485.        asm    cld            // move forwards
  486.        asm    rep movsb
  487.  
  488.        asm    pop    ds
  489.        asm    pop    di
  490.        asm    pop    si
  491.       }
  492.    }
  493.  
  494. }
  495.